package vip.liux.contracts.repositories.coupon;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.ListPagingAndSortingRepository;
import org.springframework.data.repository.NoRepositoryBean;
import vip.liux.contracts.models.coupon.UserCoupon;
import vip.liux.contracts.shared.enums.coupon.UsedTag;
import vip.liux.contracts.shared.value.ReceivedRecord;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 用户优惠券仓库接口，定义了对用户优惠券相关数据的增删查改及自定义查询方法。
 * 继承自ListPagingAndSortingRepository和ListCrudRepository，支持分页、排序及基础CRUD操作。
 */
@NoRepositoryBean
public interface UserCouponRepository extends ListPagingAndSortingRepository<UserCoupon, Long>, ListCrudRepository<UserCoupon, Long> {

    /**
     * 根据一组优惠券编号，统计每个用户领取的优惠券数量。
     *
     * @param couponNos 优惠券编号集合
     * @return 用户领取记录列表
     */
    List<ReceivedRecord> findCountUserIdByCouponNoIn(Set<String> couponNos);

    /**
     * 查询指定用户领取指定优惠券的数量。
     *
     * @param userId   用户ID
     * @param couponNo 优惠券编号
     * @return 领取数量
     */
    long findCountByUserIdAndCoupon(Long userId, String couponNo);

    /**
     * 查询指定优惠券被领取的总数量。
     *
     * @param couponNo 优惠券编号
     * @return 领取数量
     */
    long findCountByCoupon(String couponNo);

    /**
     * 查询指定用户在指定使用状态下的所有优惠券。
     *
     * @param userId  用户ID
     * @param usedTag 使用状态
     * @return 用户优惠券列表
     */
    List<UserCoupon> findByUserIdAndUsedTag(Long userId, UsedTag usedTag);

    /**
     * 根据ID和券码查询用户优惠券。
     *
     * @param id   用户优惠券ID
     * @param code 券码
     * @return 用户优惠券（可选）
     */
    Optional<UserCoupon> findByIdAndCode(Long id, String code);

    /**
     * 查询指定用户的所有优惠券。
     *
     * @param userId 用户ID
     * @return 用户优惠券列表
     */
    List<UserCoupon> findByUserId(Long userId);

    /**
     * 更新指定用户的已过期优惠券状态。
     *
     * @param userId  用户ID
     * @param usedTag 新的使用状态
     * @param now     当前时间
     * @return 更新的记录数
     */
    int updateExpiredCoupons(Long userId, UsedTag usedTag, LocalDateTime now);

    /**
     * 根据ID更新指定优惠券的过期状态。
     *
     * @param id      用户优惠券ID
     * @param usedTag 新的使用状态
     * @param now     当前时间
     * @return 更新的记录数
     */
    int updateExpiredCouponsById(List<Long> id, UsedTag usedTag, LocalDateTime now);

    /**
     * 分页查询用户优惠券。
     *
     * @param couponNo     优惠券编号
     * @param couponName   优惠券名称
     * @param userId       用户ID
     * @param usedTag      使用状态
     * @param receiveStart 领取开始时间
     * @param receiveEnd   领取结束时间
     * @param page         分页请求参数
     * @return 用户优惠券分页结果
     */
    Page<UserCoupon> getUserCoupons(String couponNo, String couponName, Long userId, UsedTag usedTag, LocalDateTime receiveStart, LocalDateTime receiveEnd, Pageable page);
}